package com.ust.tk.simpletool;

import java.io.IOException;
import java.util.List;

import android.hardware.Camera;
import android.hardware.Camera.Size;
import android.os.Build;
import android.os.Bundle;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Menu;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class TestActivity extends Activity {
	private Camera mCamera;
	private CameraPreview mCameraPreview;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_test);
		mCameraPreview = (CameraPreview)findViewById(R.id.surfaceView3);
		if ( safeCameraOpen(0) )
			mCameraPreview.setCamera(mCamera);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.test, menu);
		return true;
	}

	@Override
	protected void onResume() {
		super.onResume();
		if ( safeCameraOpen(0) )
			mCameraPreview.setCamera(mCamera);
	}
	@Override
	protected void onPause() {
		super.onPause();
		releaseCameraAndPreview();
	}
	@Override
	protected void onStop() {
		super.onStop();
		releaseCameraAndPreview();
	}

	@TargetApi(Build.VERSION_CODES.GINGERBREAD) private boolean safeCameraOpen(int id) {
	    boolean qOpened = false;
	  
	    try {
	        releaseCameraAndPreview();
	        mCamera = ( id <= 0 ) ? Camera.open() : Camera.open(id);
	        qOpened = (mCamera != null);
	    } catch (Exception e) {
	        Log.e("", "failed to open Camera");
	        e.printStackTrace();
	    }

	    return qOpened;    
	}

	private void releaseCameraAndPreview() {
		mCameraPreview.setCamera(null);
	    if (mCamera != null) {
	        mCamera.release();
	        mCamera = null;
	    }
	}
	
}

class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
	Camera mCamera;
	SurfaceHolder mHolder;
	//Size mPreviewSize = new Size(0, 0);
	//List<Size> mSupportedPreviewSizes = new List<Size>;
	
	@SuppressWarnings("deprecation")
	public CameraPreview(Context context, AttributeSet attrs) {
		super(context, attrs);

		mHolder = getHolder();
		mHolder.addCallback(this);
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
	}
	
	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
	    // Now that the size is known, set up the camera parameters and begin
	    // the preview.
		if ( mCamera != null ) {
		    Camera.Parameters parameters = mCamera.getParameters();
		    parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
		    //requestLayout();
		    mCamera.setParameters(parameters);
	
		    /*
		      Important: Call startPreview() to start updating the preview surface. Preview must be
		      started before you can take a picture.
		    */
		    mCamera.startPreview();
		    mCamera.setDisplayOrientation();
		}
	}
	
	 public static void getCameraDisplayOrientation(Activity activity,
	         int cameraId, android.hardware.Camera camera) {
	     android.hardware.Camera.CameraInfo info =
	             new android.hardware.Camera.CameraInfo();
	     android.hardware.Camera.getCameraInfo(cameraId, info);

	     int rotation = activity.getWindowManager().getDefaultDisplay()
	             .getRotation();
	     int degrees = 0;
	     switch (rotation) {
	         case Surface.ROTATION_0: degrees = 0; break;
	         case Surface.ROTATION_90: degrees = 90; break;
	         case Surface.ROTATION_180: degrees = 180; break;
	         case Surface.ROTATION_270: degrees = 270; break;
	     }

	     int result;
	     if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
	         result = (info.orientation + degrees) % 360;
	         result = (360 - result) % 360;  // compensate the mirror
	     } else {  // back-facing
	         result = (info.orientation - degrees + 360) % 360;
	     }
	     camera.setDisplayOrientation(result);
	 }


	@Override
	public void surfaceCreated(SurfaceHolder holder) {
        try {
            mCamera.setPreviewDisplay(holder);
        } catch (IOException e) {
            e.printStackTrace();
        }
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
	    // Surface will be destroyed when we return, so stop the preview.
	    if (mCamera != null) {
	        /*
	          Call stopPreview() to stop updating the preview surface.
	        */
	        mCamera.stopPreview();
	    }
	}
	
	/**
	  * When this function returns, mCamera will be null.
	  */
	private void stopPreviewAndFreeCamera() {
	    if (mCamera != null) {
	        /*
	          Call stopPreview() to stop updating the preview surface.
	        */
	        mCamera.stopPreview();
	        /*
	          Important: Call release() to release the camera for use by other applications. 
	          Applications should release the camera immediately in onPause() (and re-open() it in
	          onResume()).
	        */
	        mCamera.release();
	        mCamera = null;
	    }
	}
	
	List<Size> mSupportedPreviewSizes;
	Size mPreviewSize;
	
	public void setCamera(Camera camera) {
	    if (mCamera == camera) { return; }
	    
	    stopPreviewAndFreeCamera();
	    
	    mCamera = camera;
	    if (mCamera != null) {
	        List<Size> localSizes = mCamera.getParameters().getSupportedPreviewSizes();
	        mSupportedPreviewSizes = localSizes;
	        mPreviewSize = mSupportedPreviewSizes.get(0);
	        /*
	          Important: Call startPreview() to start updating the preview surface. Preview must 
	          be started before you can take a picture.
	          */
	        mCamera.startPreview();
	    }
	}	
}